package com.design.reactor.stretchIO;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class NioServer {
	private static Map<String,SocketChannel>  clientMap =new HashMap<>();

	public static void main(String[] args) throws IOException {

		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		serverSocketChannel.configureBlocking(false);
		serverSocketChannel.bind(new InetSocketAddress(8899));
		Selector selector = Selector.open();
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

		while(selector.select()>0) {
			Set<SelectionKey> selectionKeys =selector.selectedKeys();
			for (SelectionKey selectionKey: selectionKeys) {
				if(selectionKey.isValid()&&selectionKey.isAcceptable()) {
					System.out.println("---- NioServer  Acceptable -----");
					ServerSocketChannel ssc =(ServerSocketChannel)selectionKey.channel();
					SocketChannel sc = ssc.accept();
					sc.configureBlocking(false);
					//注册事件
					sc.register(selector, SelectionKey.OP_READ);
					// 存储客户端
					String key ="【"+sc.getRemoteAddress()+"】";
					clientMap.put(key, sc);
				}else if(selectionKey.isValid()&&selectionKey.isReadable()) {
					ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
					System.out.println("---- NioServer  Readable -----");
					SocketChannel sc =(SocketChannel)selectionKey.channel();
					try{
						 int count = sc.read(byteBuffer);
						 byteBuffer.flip();
						 if(count>0) {
							 Charset charset =Charset.forName("UTF-8");
							 String msg = String.valueOf(charset.decode(byteBuffer).array());
							 System.out.println(sc.getLocalAddress() + " 客户端发送的信息 ： " + msg);
							 // 消息分发
							 for (Entry<String, SocketChannel>  entry: clientMap.entrySet()) {
								byteBuffer.clear();
								if(entry.getValue().equals(sc)) {
									byteBuffer.put(("自己发送的消息  :  "+ msg).getBytes());
								}else {
									byteBuffer.put( (entry.getKey() +"客户端发送的消息  :  "+ msg).getBytes() );
								}
								byteBuffer.flip();
								entry.getValue().write(byteBuffer);
							 }
						 }
					}catch (Exception e){
						selectionKey.cancel();
					}
				}
//				else if(selectionKey.isValid()&&selectionKey.isWritable()){
//					ByteBuffer bb = ByteBuffer.allocate(1024);
//					System.out.println("---- NioServer  Writable -----");
//				}
				selectionKeys.remove(selectionKey);
			}
		}
	}
}
